#include "stdint.h"
#include "DevicesHash.h"


uint32_t uiSDBMHash(const void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = (uint8_t *)pvDatas;
    uint32_t uiHash = 0;

    while((iLength--) > 0)
    {
        uiHash = (uiHash << 6) + (uiHash << 16) - uiHash + *pucDatas++;
    }

    return uiHash & 0x7FFFFFFF;
}

uint32_t uiRSHash(const void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = (uint8_t *)pvDatas;
    uint32_t uiHash = 0, a = 63689;

    while((iLength--) > 0)
    {
        uiHash = uiHash * a + *pucDatas++;
        a *= 378551;
    }

    return uiHash & 0x7FFFFFFF;
}

uint32_t uiJSHash(const void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = (uint8_t *)pvDatas;
    uint32_t uiHash = 1315423911;

    while((iLength--) > 0)
    {
        uiHash ^= (uiHash << 5) + (uiHash >> 2) + *pucDatas++;
    }

    return uiHash & 0x7FFFFFFF;
}

uint32_t uiELFHash(const void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = (uint8_t *)pvDatas;
    uint32_t uiHash = 0, x = 0;

    while((iLength--) > 0)
    {
        uiHash = (uiHash << 4) + *pucDatas++;

        if ((x = uiHash & 0xF0000000L) != 0)
        {
            uiHash = (uiHash ^ (x >> 24)) & ~x;
        }
    }

    return uiHash & 0x7FFFFFFF;
}

uint32_t uiBKDRHash(const void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = (uint8_t *)pvDatas;
    uint32_t uiHash = 0, seed = 131; // 31 131 1313 13131 131313 etc..

    while((iLength--) > 0)
    {
        uiHash = uiHash * seed + *pucDatas++;
    }

    return uiHash & 0x7FFFFFFF;
}

uint32_t uiDJBHash(const void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = (uint8_t *)pvDatas;
    uint32_t uiHash = 5381;

    while((iLength--) > 0)
    {
        uiHash += (uiHash << 5) + *pucDatas++;
    }

    return uiHash & 0x7FFFFFFF;
}

uint32_t uiAPHash(const void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = (uint8_t *)pvDatas;
    uint32_t uiHash = 0;
    int32_t i = 0;

    for(i = 0; i < iLength; ++i)
    {
        uiHash ^= (i & 1) ? ~((uiHash << 11) ^ (*pucDatas++) ^ (uiHash >> 5)) : (uiHash << 7) ^ (*pucDatas++) ^ (uiHash >> 3);
    }

    return uiHash & 0x7FFFFFFF;
}
